using Data;
using JsonFx.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

public class EditGenerator
{
    private enum Direction
    {
        U,
        D,
        L,
        R
    }

    private string modeName;

    private string packageName;

    private int width = 5;

    private int height = 5;

    private int widthMin = 5;

    private int widthMax = 5;

    private int heightMin = 5;

    private int heightMax = 5;

    private int minBlockTile = 4;

    private int maxBlockTile = 6;

    private int blockCount = 4;

    private int overlapBlockCount = 999;

    private int shapeCount;

    private bool isReverse;

    private Point minPoint = new Point(0, 0);

    private bool isUpdate;

    private string pictureTheme;

    private string pictureName;

    private bool isDouble;

    private bool isRotate;

    private bool isFake;

    private bool isCustomBoard;

    private int fakeCount;

    private int vacancyPermitCount = 1;

    private int totalBoardCount;

    private int[][] customBoard;

    private int[][] board;

    private int[][] copyBoard;

    private int[][] boardColor;

    private List<int> blockCountGroup = new List<int>();

    private List<Level> generatorLevels = new List<Level>();

    private List<List<Point>> vacancyGroup = new List<List<Point>>();

    public void GeneratorLevel(string _modeName, string _packageName, string _pictureTheme, string _pictureName, int _levelCount, int _widthMin, int _widthMax, int _heightMin, int _heightMax, int _minBlockTile, int _maxBlockTile, int _blockCount, int _overlapBlockCount, bool _isDouble, bool _isRotate, bool _isFake, int _fakeCount, bool _isCustomBoard, int[][] _customBoard, bool _isReverse, Point _minPoint, int[][] _boardColor, bool _isUpdate, int index = -1)
    {
        generatorLevels.Clear();
        modeName = _modeName;
        packageName = _packageName;
        pictureTheme = _pictureTheme;
        pictureName = _pictureName;
        widthMin = _widthMin;
        widthMax = _widthMax;
        heightMin = _heightMin;
        heightMax = _heightMax;
        minBlockTile = _minBlockTile;
        maxBlockTile = _maxBlockTile;
        blockCount = _blockCount;
        isReverse = _isReverse;
        minPoint = _minPoint;
        isUpdate = _isUpdate;
        overlapBlockCount = _overlapBlockCount;
        isDouble = _isDouble;
        isRotate = _isRotate;
        isFake = _isFake;
        fakeCount = _fakeCount;
        customBoard = _customBoard;
        isCustomBoard = _isCustomBoard;
        boardColor = _boardColor;
        if (isFake && fakeCount < 0)
        {
            UnityEngine.Debug.LogError("fakeCount 0");
            return;
        }
        if (string.IsNullOrEmpty(packageName))
        {
            UnityEngine.Debug.LogError("Fill PackageName");
            return;
        }
        if (!isCustomBoard && (maxBlockTile * blockCount < _widthMin * _heightMin - shapeCount || minBlockTile * blockCount > _widthMax * _heightMax - shapeCount))
        {
            UnityEngine.Debug.LogError("Not Invalide");
            return;
        }
        if (isCustomBoard)
        {
            blockCountGroup.Clear();
            width = customBoard.GetLength(0);
            height = customBoard[0].Length;
            totalBoardCount = 0;
            for (int i = 0; i < width; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    if (customBoard[i][j] == 0)
                    {
                        totalBoardCount++;
                    }
                }
            }
            if (maxBlockTile * blockCount < totalBoardCount || minBlockTile * blockCount > totalBoardCount)
            {
                UnityEngine.Debug.LogError("Not Invalide");
                return;
            }
        }
        int num = 0;
        int num2 = 0;
        for (int k = 0; k < _levelCount; k++)
        {
            bool flag = false;
            if (isCustomBoard)
            {
                if (!CostomInit())
                {
                    continue;
                }
            }
            else if (!Init())
            {
                continue;
            }
            vacancyPermitCount = VacancyGroup(board).Count;
            InitBlockCountGroup();
            if (SetRandomLevel(isRandomGeneration: false))
            {
                num2++;
                generatorLevels.Add(ConvertData());
                continue;
            }
            num++;
            k--;
            if (num <= 100)
            {
                continue;
            }
            break;
        }
        UnityEngine.Debug.Log("try : " + _levelCount + "  success : " + num2);
        if (num2 > 0)
        {
            Save(index);
        }
    }

    public void RandomGeneratorLevel(string _modeName, string _packageName, string _pictureTheme, string _pictureName, int _levelCount, int _minBlockTile, int _maxBlockTile, int _blockCount, bool _isFake, int _fakeCount, int _overlapBlockCount, bool _isUpdate, int index = -1)
    {
        generatorLevels.Clear();
        modeName = _modeName;
        packageName = _packageName;
        pictureTheme = _pictureTheme;
        pictureName = _pictureName;
        minBlockTile = _minBlockTile;
        maxBlockTile = _maxBlockTile;
        isDouble = false;
        isRotate = false;
        isFake = _isFake;
        fakeCount = _fakeCount;
        blockCount = _blockCount;
        isReverse = false;
        minPoint = new Point(0, 0);
        isUpdate = _isUpdate;
        overlapBlockCount = _overlapBlockCount;
        if (string.IsNullOrEmpty(packageName))
        {
            UnityEngine.Debug.LogError("Fill PackageName");
            return;
        }
        if (isFake && fakeCount < 0)
        {
            UnityEngine.Debug.LogError("fakeCount 0");
            return;
        }
        for (int i = 0; i < _levelCount; i++)
        {
            InitMaxBoard();
            bool flag = false;
            for (int j = 0; j < 10; j++)
            {
                int num = 0;
                for (int k = 0; k < blockCount; k++)
                {
                    int num2 = UnityEngine.Random.Range(minBlockTile, maxBlockTile + 1);
                    blockCountGroup.Add(num2);
                    num += num2;
                }
                if (BlocksCoordinate.coordinate.defaultCoordinate.width * BlocksCoordinate.coordinate.defaultCoordinate.height > num)
                {
                    flag = true;
                    break;
                }
                blockCountGroup.Clear();
            }
            if (!flag)
            {
                UnityEngine.Debug.LogError("Board Size Not Vaild");
                break;
            }
            vacancyPermitCount = 1;
            SetRandomLevel(isRandomGeneration: true);
            copyBoard = Copy(board);
            int num3 = 9999;
            int num4 = -9999;
            int num5 = 9999;
            int num6 = -9999;
            for (int l = 0; l < BlocksCoordinate.coordinate.defaultCoordinate.width; l++)
            {
                for (int m = 0; m < BlocksCoordinate.coordinate.defaultCoordinate.height; m++)
                {
                    if (board[l][m] != 0)
                    {
                        if (num3 > l)
                        {
                            num3 = l;
                        }
                        if (num4 < l)
                        {
                            num4 = l;
                        }
                        if (num5 > m)
                        {
                            num5 = m;
                        }
                        if (num6 < m)
                        {
                            num6 = m;
                        }
                    }
                }
            }
            width = num4 - num3 + 1;
            height = num6 - num5 + 1;
            isReverse = ((num3 + num5) % 2 != 0);
            minPoint = new Point(num3, num5);
            board = new int[width][];
            for (int n = 0; n < width; n++)
            {
                board[n] = new int[height];
                for (int num7 = 0; num7 < height; num7++)
                {
                    board[n][num7] = 0;
                }
            }
            for (int num8 = 0; num8 < BlocksCoordinate.coordinate.defaultCoordinate.width; num8++)
            {
                for (int num9 = 0; num9 < BlocksCoordinate.coordinate.defaultCoordinate.height; num9++)
                {
                    if (copyBoard[num8][num9] != 0)
                    {
                        board[num8 - num3][num9 - num5] = copyBoard[num8][num9];
                    }
                }
            }
            generatorLevels.Add(ConvertData());
        }
        Save(index);
    }

    private bool SetRandomLevel(bool isRandomGeneration)
    {
        bool flag = true;
        int num = 0;
        for (int i = 0; i < blockCountGroup.Count; i++)
        {
            copyBoard = Copy(board);
            Point point = new Point(0, 0);
            if (flag)
            {
                List<Point> list = new List<Point>();
                for (int j = 0; j < copyBoard.GetLength(0); j++)
                {
                    for (int k = 0; k < copyBoard[j].Length; k++)
                    {
                        if (copyBoard[j][k] == 0)
                        {
                            list.Add(new Point(j, k));
                        }
                    }
                }
                point = list[UnityEngine.Random.Range(0, list.Count)];
            }
            else if (isRandomGeneration)
            {
                List<Point> list2 = new List<Point>();
                for (int l = 0; l < copyBoard.GetLength(0); l++)
                {
                    for (int m = 0; m < copyBoard[l].Length; m++)
                    {
                        if (copyBoard[l][m] > 0)
                        {
                            list2.Add(new Point(l, m));
                        }
                    }
                }
                list2 = ShuppleList(list2);
                for (int n = 0; n < list2.Count; n++)
                {
                    List<Point> list3 = new List<Point>();
                    if (GameMode.gameMode == GameType.TRIANGLE)
                    {
                        list3 = GetTriangleNeighborPoints(list2[n]);
                    }
                    else if (GameMode.gameMode == GameType.SQUARE)
                    {
                        list3 = GetSquareNeighborPoints(list2[n]);
                    }
                    else if (GameMode.gameMode == GameType.HEXA)
                    {
                        list3 = GetHexaNeighborPoints(list2[n]);
                    }
                    else if (GameMode.gameMode == GameType.RHOMBUS)
                    {
                        list3 = GetRhombusNeighborPoints(list2[n]);
                    }
                    else if (GameMode.gameMode == GameType.TANGRAM)
                    {
                        list3 = GetTangramNeighborPoints(list2[n]);
                    }
                    if (list3.Count > 0)
                    {
                        point = list3[UnityEngine.Random.Range(0, list3.Count)];
                        break;
                    }
                }
            }
            else
            {
                List<Point> list4 = new List<Point>();
                for (int num2 = 0; num2 < copyBoard.GetLength(0); num2++)
                {
                    for (int num3 = 0; num3 < copyBoard[num2].Length; num3++)
                    {
                        if (copyBoard[num2][num3] == 0)
                        {
                            list4.Add(new Point(num2, num3));
                        }
                    }
                }
                point = list4[UnityEngine.Random.Range(0, list4.Count)];
            }
            for (int num4 = 0; num4 < blockCountGroup[i]; num4++)
            {
                if (num4 == 0)
                {
                    copyBoard[point.x][point.y] = i + 1;
                    continue;
                }
                List<Point> list5 = new List<Point>();
                for (int num5 = 0; num5 < copyBoard.GetLength(0); num5++)
                {
                    for (int num6 = 0; num6 < copyBoard[num5].Length; num6++)
                    {
                        if (copyBoard[num5][num6] == i + 1)
                        {
                            list5.Add(new Point(num5, num6));
                        }
                    }
                }
                bool flag2 = false;
                list5 = ShuppleList(list5);
                for (int num7 = 0; num7 < list5.Count; num7++)
                {
                    List<Point> list6 = new List<Point>();
                    if (GameMode.gameMode == GameType.TRIANGLE)
                    {
                        list6 = GetTriangleNeighborPoints(list5[num7]);
                    }
                    else if (GameMode.gameMode == GameType.SQUARE)
                    {
                        list6 = GetSquareNeighborPoints(list5[num7]);
                    }
                    else if (GameMode.gameMode == GameType.HEXA)
                    {
                        list6 = GetHexaNeighborPoints(list5[num7]);
                    }
                    else if (GameMode.gameMode == GameType.RHOMBUS)
                    {
                        list6 = GetRhombusNeighborPoints(list5[num7]);
                    }
                    else if (GameMode.gameMode == GameType.TANGRAM)
                    {
                        list6 = GetTangramNeighborPoints(list5[num7]);
                    }
                    if (list6.Count > 0)
                    {
                        Point point2 = list6[UnityEngine.Random.Range(0, list6.Count)];
                        copyBoard[point2.x][point2.y] = i + 1;
                        flag2 = true;
                        break;
                    }
                }
                if (!flag2)
                {
                    return false;
                }
            }
            if (VacancyGroup(copyBoard).Count > vacancyPermitCount)
            {
                i--;
                num++;
            }
            else
            {
                board = Copy(copyBoard);
                vacancyPermitCount = VacancyGroup(copyBoard).Count;
                flag = false;
            }
            if (num > 100)
            {
                return false;
            }
        }
        return true;
    }

    private List<Point> GetTriangleNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        bool flag = false;
        flag = (isReverse ? (((point.x + point.y) % 2 != 0) ? true : false) : (((point.x + point.y) % 2 == 0) ? true : false));
        if (!flag && point.y + 1 < copyBoard[point.x].Length && copyBoard[point.x][point.y + 1] == 0)
        {
            list.Add(new Point(point.x, point.y + 1));
        }
        if (flag && point.y - 1 >= 0 && copyBoard[point.x][point.y - 1] == 0)
        {
            list.Add(new Point(point.x, point.y - 1));
        }
        if (point.x + 1 < copyBoard.GetLength(0) && copyBoard[point.x + 1][point.y] == 0)
        {
            list.Add(new Point(point.x + 1, point.y));
        }
        if (point.x - 1 >= 0 && copyBoard[point.x - 1][point.y] == 0)
        {
            list.Add(new Point(point.x - 1, point.y));
        }
        return list;
    }

    private List<Point> GetSquareNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        if (point.y + 1 < copyBoard[point.x].Length && copyBoard[point.x][point.y + 1] == 0)
        {
            list.Add(new Point(point.x, point.y + 1));
        }
        if (point.y - 1 >= 0 && copyBoard[point.x][point.y - 1] == 0)
        {
            list.Add(new Point(point.x, point.y - 1));
        }
        if (point.x + 1 < copyBoard.GetLength(0) && copyBoard[point.x + 1][point.y] == 0)
        {
            list.Add(new Point(point.x + 1, point.y));
        }
        if (point.x - 1 >= 0 && copyBoard[point.x - 1][point.y] == 0)
        {
            list.Add(new Point(point.x - 1, point.y));
        }
        return list;
    }

    private List<Point> GetHexaNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        if (point.y + 1 < copyBoard[point.x].Length && copyBoard[point.x][point.y + 1] == 0)
        {
            list.Add(new Point(point.x, point.y + 1));
        }
        if (point.y - 1 >= 0 && copyBoard[point.x][point.y - 1] == 0)
        {
            list.Add(new Point(point.x, point.y - 1));
        }
        if (point.x + 1 < copyBoard.GetLength(0) && (point.x % 2 == 0 || point.y != copyBoard[point.x].Length - 1))
        {
            if (point.x % 2 == 0 && copyBoard[point.x + 1][point.y] == 0)
            {
                list.Add(new Point(point.x + 1, point.y));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x + 1][point.y + 1] == 0)
            {
                list.Add(new Point(point.x + 1, point.y + 1));
            }
        }
        if (point.x + 1 < copyBoard.GetLength(0) && (point.x % 2 != 0 || point.y != 0))
        {
            if (point.x % 2 == 0 && copyBoard[point.x + 1][point.y - 1] == 0)
            {
                list.Add(new Point(point.x + 1, point.y - 1));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x + 1][point.y] == 0)
            {
                list.Add(new Point(point.x + 1, point.y));
            }
        }
        if (point.x - 1 >= 0 && (point.x % 2 == 0 || point.y != copyBoard[point.x].Length - 1))
        {
            if (point.x % 2 == 0 && copyBoard[point.x - 1][point.y] == 0)
            {
                list.Add(new Point(point.x - 1, point.y));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x - 1][point.y + 1] == 0)
            {
                list.Add(new Point(point.x - 1, point.y + 1));
            }
        }
        if (point.x - 1 >= 0 && (point.x % 2 != 0 || point.y != 0))
        {
            if (point.x % 2 == 0 && copyBoard[point.x - 1][point.y - 1] == 0)
            {
                list.Add(new Point(point.x - 1, point.y - 1));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x - 1][point.y] == 0)
            {
                list.Add(new Point(point.x - 1, point.y));
            }
        }
        return list;
    }

    private List<Point> GetRhombusNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        if (point.x + 1 < copyBoard.GetLength(0) && (point.x % 2 == 0 || point.y != copyBoard[point.x].Length - 1))
        {
            if (point.x % 2 == 0 && copyBoard[point.x + 1][point.y] == 0)
            {
                list.Add(new Point(point.x + 1, point.y));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x + 1][point.y + 1] == 0)
            {
                list.Add(new Point(point.x + 1, point.y + 1));
            }
        }
        if (point.x + 1 < copyBoard.GetLength(0) && (point.x % 2 != 0 || point.y != 0))
        {
            if (point.x % 2 == 0 && copyBoard[point.x + 1][point.y - 1] == 0)
            {
                list.Add(new Point(point.x + 1, point.y - 1));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x + 1][point.y] == 0)
            {
                list.Add(new Point(point.x + 1, point.y));
            }
        }
        if (point.x - 1 >= 0 && (point.x % 2 == 0 || point.y != copyBoard[point.x].Length - 1))
        {
            if (point.x % 2 == 0 && copyBoard[point.x - 1][point.y] == 0)
            {
                list.Add(new Point(point.x - 1, point.y));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x - 1][point.y + 1] == 0)
            {
                list.Add(new Point(point.x - 1, point.y + 1));
            }
        }
        if (point.x - 1 >= 0 && (point.x % 2 != 0 || point.y != 0))
        {
            if (point.x % 2 == 0 && copyBoard[point.x - 1][point.y - 1] == 0)
            {
                list.Add(new Point(point.x - 1, point.y - 1));
            }
            else if (point.x % 2 != 0 && copyBoard[point.x - 1][point.y] == 0)
            {
                list.Add(new Point(point.x - 1, point.y));
            }
        }
        return list;
    }

    private List<Point> GetTangramNeighborPoints(Point point)
    {
        List<Point> list = new List<Point>();
        int num = (point.x + minPoint.x + (((point.y + minPoint.y) % 2 != 0) ? 2 : 0)) % 4;
        if (point.x + 1 < copyBoard.GetLength(0) && copyBoard[point.x + 1][point.y] == 0)
        {
            list.Add(new Point(point.x + 1, point.y));
        }
        if (point.x - 1 >= 0 && copyBoard[point.x - 1][point.y] == 0)
        {
            list.Add(new Point(point.x - 1, point.y));
        }
        if ((num == 1 || num == 2) && point.y + 1 < copyBoard[point.x].Length && copyBoard[point.x][point.y + 1] == 0)
        {
            list.Add(new Point(point.x, point.y + 1));
        }
        if ((num == 0 || num == 3) && point.y - 1 >= 0 && copyBoard[point.x][point.y - 1] == 0)
        {
            list.Add(new Point(point.x, point.y - 1));
        }
        return list;
    }

    private bool CostomInit()
    {
        blockCountGroup.Clear();
        if (maxBlockTile * blockCount < totalBoardCount || minBlockTile * blockCount > totalBoardCount)
        {
            return false;
        }
        board = new int[width][];
        for (int i = 0; i < width; i++)
        {
            board[i] = new int[height];
            for (int j = 0; j < height; j++)
            {
                board[i][j] = customBoard[i][j];
            }
        }
        return true;
    }

    private bool Init()
    {
        blockCountGroup.Clear();
        width = UnityEngine.Random.Range(widthMin, widthMax + 1);
        height = UnityEngine.Random.Range(heightMin, heightMax + 1);
        totalBoardCount = width * height - shapeCount;
        if (maxBlockTile * blockCount < totalBoardCount || minBlockTile * blockCount > totalBoardCount)
        {
            return false;
        }
        board = new int[width][];
        for (int i = 0; i < width; i++)
        {
            board[i] = new int[height];
            for (int j = 0; j < height; j++)
            {
                board[i][j] = 0;
            }
        }
        for (int k = 0; k < shapeCount; k++)
        {
            int num = UnityEngine.Random.Range(0, width);
            int num2 = UnityEngine.Random.Range(0, height);
            if (board[num][num2] == 0)
            {
                board[num][num2] = -1;
            }
            else
            {
                k--;
            }
        }
        return true;
    }

    private bool InitMaxBoard()
    {
        blockCountGroup.Clear();
        width = BlocksCoordinate.coordinate.defaultCoordinate.width;
        height = BlocksCoordinate.coordinate.defaultCoordinate.height;
        board = new int[width][];
        for (int i = 0; i < width; i++)
        {
            board[i] = new int[height];
            for (int j = 0; j < height; j++)
            {
                board[i][j] = 0;
            }
        }
        return true;
    }

    private void InitBlockCountGroup()
    {
        blockCountGroup.Clear();
        int num = 0;
        for (int i = 0; i < blockCount; i++)
        {
            int num2 = UnityEngine.Random.Range(minBlockTile, maxBlockTile + 1);
            blockCountGroup.Add(num2);
            num += num2;
        }
        int num3 = 0;
        while (true)
        {
            int index = num3 % blockCount;
            if (num > totalBoardCount)
            {
                num -= blockCountGroup[index];
                int num4 = UnityEngine.Random.Range(minBlockTile, blockCountGroup[index] + 1);
                blockCountGroup[index] = num4;
                num += num4;
            }
            else
            {
                if (num >= totalBoardCount)
                {
                    break;
                }
                num -= blockCountGroup[index];
                int num5 = UnityEngine.Random.Range(blockCountGroup[index], maxBlockTile + 1);
                blockCountGroup[index] = num5;
                num += num5;
            }
            num3++;
        }
        blockCountGroup = ShuppleList(blockCountGroup);
    }

    private bool IsTwoEqualsBlock(byte[][] _board = null)
    {
        byte[][] array = (_board != null) ? Copy2(_board) : Copy2(ConvertLevel());
        for (int i = 0; i < array.GetLength(0); i++)
        {
            byte b = array[i][0];
            for (int j = 0; j < array[i].Length; j++)
            {
                array[i][j] = (byte)(array[i][j] - b);
            }
        }
        for (int k = 0; k < array.Length; k++)
        {
            int num = 0;
            for (int l = k + 1; l < array.Length; l++)
            {
                if (isSameArray(array[k], array[l]))
                {
                    num++;
                }
                if (num > overlapBlockCount)
                {
                    return true;
                }
            }
        }
        return false;
    }

    public Point IndexToPuzzle(int index)
    {
        Point result = default(Point);
        result.x = index % width;
        result.y = index / width;
        return result;
    }

    private bool isSameArray(byte[] array1, byte[] array2)
    {
        if (array1.Length != array2.Length)
        {
            return false;
        }
        for (int i = 0; i < array1.Length; i++)
        {
            if (array1[i] != array2[i])
            {
                return false;
            }
        }
        return true;
    }

    private List<List<Point>> VacancyGroup(int[][] _copyBoard)
    {
        bool[][] array = new bool[width][];
        for (int i = 0; i < width; i++)
        {
            array[i] = new bool[height];
            for (int j = 0; j < height; j++)
            {
                array[i][j] = ((_copyBoard[i][j] == 0) ? true : false);
            }
        }
        vacancyGroup.Clear();
        vacancyGroup = new List<List<Point>>();
        for (int k = 0; k < height; k++)
        {
            for (int l = 0; l < width; l++)
            {
                if (!array[l][k])
                {
                    continue;
                }
                List<Point> list = new List<Point>();
                list.Add(new Point(l, k));
                array[l][k] = false;
                for (int m = 0; m < list.Count; m++)
                {
                    bool flag = false;
                    if (!isReverse)
                    {
                        Point point = list[m];
                        int num = point.x % 2;
                        Point point2 = list[m];
                        flag = (num != point2.y % 2);
                    }
                    else
                    {
                        Point point3 = list[m];
                        int num2 = point3.x % 2;
                        Point point4 = list[m];
                        flag = (num2 == point4.y % 2);
                    }
                    Point point5 = list[m];
                    if (point5.y + 1 < height && flag)
                    {
                        bool[][] array2 = array;
                        Point point6 = list[m];
                        bool[] obj = array2[point6.x];
                        Point point7 = list[m];
                        if (obj[point7.y + 1])
                        {
                            bool[][] array3 = array;
                            Point point8 = list[m];
                            bool[] obj2 = array3[point8.x];
                            Point point9 = list[m];
                            obj2[point9.y + 1] = false;
                            List<Point> list2 = list;
                            Point point10 = list[m];
                            int x = point10.x;
                            Point point11 = list[m];
                            list2.Add(new Point(x, point11.y + 1));
                        }
                    }
                    Point point12 = list[m];
                    if (point12.y - 1 >= 0 && !flag)
                    {
                        bool[][] array4 = array;
                        Point point13 = list[m];
                        bool[] obj3 = array4[point13.x];
                        Point point14 = list[m];
                        if (obj3[point14.y - 1])
                        {
                            bool[][] array5 = array;
                            Point point15 = list[m];
                            bool[] obj4 = array5[point15.x];
                            Point point16 = list[m];
                            obj4[point16.y - 1] = false;
                            List<Point> list3 = list;
                            Point point17 = list[m];
                            int x2 = point17.x;
                            Point point18 = list[m];
                            list3.Add(new Point(x2, point18.y - 1));
                        }
                    }
                    Point point19 = list[m];
                    if (point19.x - 1 >= 0)
                    {
                        bool[][] array6 = array;
                        Point point20 = list[m];
                        bool[] obj5 = array6[point20.x - 1];
                        Point point21 = list[m];
                        if (obj5[point21.y])
                        {
                            bool[][] array7 = array;
                            Point point22 = list[m];
                            bool[] obj6 = array7[point22.x - 1];
                            Point point23 = list[m];
                            obj6[point23.y] = false;
                            List<Point> list4 = list;
                            Point point24 = list[m];
                            int x3 = point24.x - 1;
                            Point point25 = list[m];
                            list4.Add(new Point(x3, point25.y));
                        }
                    }
                    Point point26 = list[m];
                    if (point26.x + 1 < width)
                    {
                        bool[][] array8 = array;
                        Point point27 = list[m];
                        bool[] obj7 = array8[point27.x + 1];
                        Point point28 = list[m];
                        if (obj7[point28.y])
                        {
                            bool[][] array9 = array;
                            Point point29 = list[m];
                            bool[] obj8 = array9[point29.x + 1];
                            Point point30 = list[m];
                            obj8[point30.y] = false;
                            List<Point> list5 = list;
                            Point point31 = list[m];
                            int x4 = point31.x + 1;
                            Point point32 = list[m];
                            list5.Add(new Point(x4, point32.y));
                        }
                    }
                }
                vacancyGroup.Add(list);
            }
        }
        return vacancyGroup;
    }

    private int[][] Copy(int[][] _copyBoard)
    {
        int[][] array = new int[width][];
        for (int i = 0; i < width; i++)
        {
            array[i] = new int[height];
            for (int j = 0; j < height; j++)
            {
                array[i][j] = _copyBoard[i][j];
            }
        }
        return array;
    }

    private byte[][] Copy2(byte[][] _copyBoard)
    {
        byte[][] array = new byte[_copyBoard.GetLength(0)][];
        for (int i = 0; i < array.GetLength(0); i++)
        {
            array[i] = new byte[_copyBoard[i].Length];
            for (int j = 0; j < array[i].Length; j++)
            {
                array[i][j] = _copyBoard[i][j];
            }
        }
        return array;
    }

    private List<T> ShuppleList<T>(List<T> suppleTarget)
    {
        List<T> list = new List<T>();
        while (suppleTarget.Count > 0)
        {
            int index = UnityEngine.Random.Range(0, suppleTarget.Count);
            list.Add(suppleTarget[index]);
            suppleTarget.RemoveAt(index);
        }
        return list;
    }

    private void PrintBoard(int[][] _board = null)
    {
        if (_board == null)
        {
            _board = board;
        }
        string text = string.Empty;
        for (int i = 0; i < blockCountGroup.Count; i++)
        {
            text = text + blockCountGroup[i] + " : ";
        }
        for (int num = height - 1; num >= 0; num--)
        {
            text += "\n";
            for (int j = 0; j < width; j++)
            {
                text = text + _board[j][num] + " ";
            }
        }
        UnityEngine.Debug.Log(text);
    }

    private List<Level> GetLevels()
    {
        string text = null;
        try
        {
            text = JsonFileSystem.Read(modeName + "/" + packageName + "_package");
            Level[] source = JsonReader.Deserialize<Level[]>(text);
            return source.ToList();
        }
        catch (FileNotFoundException message)
        {
            UnityEngine.Debug.Log(message);
            return new List<Level>();
        }
    }

    public void ChangeLevel(string _modeName, string _packageName, int index1, int index2)
    {
        modeName = _modeName;
        packageName = _packageName;
        List<Level> list = new List<Level>();
        List<Level> levels = GetLevels();
        for (int i = 0; i < levels.Count; i++)
        {
            if (i == index1)
            {
                list.Add(levels[index2]);
            }
            else if (i == index2)
            {
                list.Add(levels[index1]);
            }
            else
            {
                list.Add(levels[i]);
            }
        }
        for (int j = 0; j < list.Count; j++)
        {
            list[j].num = j;
        }
        string contents = JsonWriter.Serialize(list);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + modeName + "/" + packageName + "_package.txt", contents);
    }

    public void Delete(string _packageName, int index)
    {
        packageName = _packageName;
        List<Level> levels = GetLevels();
        List<Level> list = new List<Level>();
        for (int i = 0; i < levels.Count; i++)
        {
            if (i != index)
            {
                list.Add(levels[i]);
            }
        }
        for (int j = 0; j < list.Count; j++)
        {
            list[j].num = j;
        }
        string contents = JsonWriter.Serialize(list);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + modeName + "/" + packageName + "_package.txt", contents);
    }

    public void ShuppleIndex(string _modeName, string _packageName, int index)
    {
        modeName = _modeName;
        packageName = _packageName;
        List<Level> levels = GetLevels();
        List<byte> list = new List<byte>();
        for (int i = 0; i < levels[index].index.Length; i++)
        {
            list.Add(levels[index].index[i]);
        }
        levels[index].index = ShuppleList(list).ToArray();
        string contents = JsonWriter.Serialize(levels);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + modeName + "/" + packageName + "_package.txt", contents);
    }

    private void Save(int index)
    {
        List<Level> levels = GetLevels();
        if (isUpdate)
        {
            for (int i = 0; i < generatorLevels.Count; i++)
            {
                levels[index + i] = generatorLevels[i];
            }
        }
        else if (index == -1)
        {
            for (int j = 0; j < generatorLevels.Count; j++)
            {
                levels.Add(generatorLevels[j]);
            }
        }
        else
        {
            for (int k = 0; k < generatorLevels.Count; k++)
            {
                levels.Insert(index, generatorLevels[k]);
            }
        }
        for (int l = 0; l < levels.Count; l++)
        {
            levels[l].num = l;
        }
        string contents = JsonWriter.Serialize(levels);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + modeName + "/" + packageName + "_package.txt", contents);
    }

    public void Overlap(string _packageName)
    {
        packageName = _packageName;
        List<Level> levels = GetLevels();
        List<Level> levels2 = GetLevels();
        for (int i = 0; i < levels.Count; i++)
        {
            for (int j = 0; j < levels2.Count; j++)
            {
                if (i != j && isSame(levels[i].level, levels2[j].level))
                {
                    UnityEngine.Debug.Log(i + " : " + j);
                }
            }
        }
    }

    private bool isSame(byte[][] level1, byte[][] level2)
    {
        if (level1.GetLength(0) == level2.GetLength(0))
        {
            for (int i = 0; i < level1.GetLength(0); i++)
            {
                if (!level1[i].SequenceEqual(level2[i]))
                {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    public void PackageOverlapBlock(string _packageName, int _overlapBlockCount)
    {
        packageName = _packageName;
        overlapBlockCount = _overlapBlockCount;
        List<Level> levels = GetLevels();
        string text = string.Empty;
        for (int i = 0; i < levels.Count; i++)
        {
            width = levels[i].width;
            if (IsTwoEqualsBlock(levels[i].level))
            {
                text = text + (i + 1) + ", ";
            }
        }
        UnityEngine.Debug.Log(text);
    }

    public void Porting(string _packageName, string _porting)
    {
        string[] array = _porting.Split(',');
        List<Level> list = new List<Level>();
        for (int i = 0; i < array.Length; i++)
        {
            string text = null;
            try
            {
                string[] array2 = array[i].Split('_');
                text = JsonFileSystem.Read("Porting/" + array2[0] + "_package");
                Level[] array3 = JsonReader.Deserialize<Level[]>(text);
                list.Add(array3[Convert.ToInt32(array2[1])]);
            }
            catch (FileNotFoundException message)
            {
                UnityEngine.Debug.LogError(message);
            }
        }
        for (int j = 0; j < list.Count; j++)
        {
            list[j].num = j;
        }
        string contents = JsonWriter.Serialize(list);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + _packageName + "_package.txt", contents);
    }

    public void SetPicture(string _modeName, string _packageName, int _index, string _pictureTheme, string _pictureName)
    {
        modeName = _modeName;
        packageName = _packageName;
        List<Level> levels = GetLevels();
        levels[_index].pictureTheme = _pictureTheme;
        levels[_index].pictureName = _pictureName;
        string contents = JsonWriter.Serialize(levels);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + modeName + "/" + packageName + "_package.txt", contents);
    }

    public void DelPicture(string _modeName, string _packageName, int _index)
    {
        modeName = _modeName;
        packageName = _packageName;
        List<Level> levels = GetLevels();
        levels[_index].pictureTheme = null;
        levels[_index].pictureName = null;
        string contents = JsonWriter.Serialize(levels);
        File.WriteAllText("Assets/Data/text/" + DataContainer<Data.Root>.GetPostfix() + "/" + modeName + "/" + packageName + "_package.txt", contents);
    }

    private Level ConvertData()
    {
        Level level = new Level();
        int num = blockCount;
        level.level = ConvertLevel();
        level.changeColor = ConvertColor();
        level.hinder = ConvertHinder();
        level.width = width;
        level.height = height;
        level.blockcount = blockCount;
        level.isReverse = isReverse;
        level.editMinPoint = new byte[2]
        {
            (byte)minPoint.x,
            (byte)minPoint.y
        };
        level.mode = (int)GameMode.gameMode;
        if (isUpdate)
        {
            level.pictureTheme = pictureTheme;
            level.pictureName = pictureName;
        }
        List<byte> list = new List<byte>();
        for (int i = 0; i < level.level.Length; i++)
        {
            list.Add((byte)i);
        }
        level.index = ShuppleList(list).ToArray();
        blockCount = num;
        return level;
    }

    private byte[] ConvertHinder()
    {
        List<Point> list = new List<Point>();
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                if (board[j][i] == -2)
                {
                    list.Add(new Point(j, i));
                }
            }
        }
        byte[] array = new byte[list.Count];
        for (int k = 0; k < list.Count; k++)
        {
            byte[] array2 = array;
            int num = k;
            Point point = list[k];
            int x = point.x;
            Point point2 = list[k];
            array2[num] = (byte)(x + point2.y * width);
        }
        return array;
    }

    private byte[][] ConvertLevel()
    {
        byte[][] array = new byte[blockCount][];
        if (isFake)
        {
            array = new byte[blockCount + fakeCount][];
        }
        for (int i = 0; i < blockCount; i++)
        {
            List<Point> list = new List<Point>();
            for (int j = 0; j < height; j++)
            {
                for (int k = 0; k < width; k++)
                {
                    if (board[k][j] == i + 1)
                    {
                        list.Add(new Point(k, j));
                    }
                }
            }
            array[i] = new byte[list.Count];
            for (int l = 0; l < list.Count; l++)
            {
                byte[] obj = array[i];
                int num = l;
                Point point = list[l];
                int x = point.x;
                Point point2 = list[l];
                obj[num] = (byte)(x + point2.y * width);
            }
        }
        if (isFake)
        {
            for (int m = blockCount; m < blockCount + fakeCount; m++)
            {
                int[][] array2 = MakeFakeBlock();
                List<Point> list2 = new List<Point>();
                for (int n = 0; n < height; n++)
                {
                    for (int num2 = 0; num2 < width; num2++)
                    {
                        if (array2[num2][n] == 1)
                        {
                            list2.Add(new Point(num2, n));
                        }
                    }
                }
                array[m] = new byte[list2.Count];
                for (int num3 = 0; num3 < list2.Count; num3++)
                {
                    byte[] obj2 = array[m];
                    int num4 = num3;
                    Point point3 = list2[num3];
                    int x2 = point3.x;
                    Point point4 = list2[num3];
                    obj2[num4] = (byte)(x2 + point4.y * width);
                }
            }
        }
        return array;
    }

    private byte[][] ConvertColor()
    {
        byte[][] array = new byte[blockCount][];
        if (isFake)
        {
            array = new byte[blockCount + fakeCount][];
        }
        for (int i = 0; i < blockCount; i++)
        {
            List<Point> list = new List<Point>();
            for (int j = 0; j < height; j++)
            {
                for (int k = 0; k < width; k++)
                {
                    if (board[k][j] == i + 1)
                    {
                        list.Add(new Point(k, j));
                    }
                }
            }
            array[i] = new byte[list.Count];
            for (int l = 0; l < list.Count; l++)
            {
                byte[] obj = array[i];
                int num = l;
                int[][] array2 = boardColor;
                Point point = list[l];
                int[] obj2 = array2[point.x];
                Point point2 = list[l];
                obj[num] = (byte)obj2[point2.y];
            }
        }
        if (isFake)
        {
            for (int m = blockCount; m < blockCount + fakeCount; m++)
            {
                int[][] array3 = MakeFakeBlock();
                List<Point> list2 = new List<Point>();
                for (int n = 0; n < height; n++)
                {
                    for (int num2 = 0; num2 < width; num2++)
                    {
                        if (array3[num2][n] == 1)
                        {
                            list2.Add(new Point(num2, n));
                        }
                    }
                }
                array[m] = new byte[list2.Count];
                for (int num3 = 0; num3 < list2.Count; num3++)
                {
                    byte[] obj3 = array[m];
                    int num4 = num3;
                    int[][] array4 = boardColor;
                    Point point3 = list2[num3];
                    int[] obj4 = array4[point3.x];
                    Point point4 = list2[num3];
                    obj3[num4] = (byte)obj4[point4.y];
                }
            }
        }
        return array;
    }

    private int[][] MakeFakeBlock()
    {
        int num = UnityEngine.Random.Range(minBlockTile, maxBlockTile + 1);
        int[][] array = new int[width][];
        for (int i = 0; i < width; i++)
        {
            array[i] = new int[height];
            for (int j = 0; j < height; j++)
            {
                array[i][j] = 0;
            }
        }
        List<Point> list = new List<Point>();
        Point item = new Point(UnityEngine.Random.Range(0, width), UnityEngine.Random.Range(0, height));
        list.Add(item);
        array[item.x][item.y] = 1;
        int num2 = 1;
        do
        {
            int index = UnityEngine.Random.Range(0, list.Count);
            List<Direction> list2 = ShuppleList(new List<Direction>
            {
                Direction.U,
                Direction.D,
                Direction.L,
                Direction.R
            });
            bool flag = false;
            for (int num3 = 0; num3 < list2.Count; num3++)
            {
                bool flag2 = false;
                if (!isReverse)
                {
                    Point point = list[index];
                    int num4 = point.x % 2;
                    Point point2 = list[index];
                    flag2 = (num4 != point2.y % 2);
                }
                else
                {
                    Point point3 = list[index];
                    int num5 = point3.x % 2;
                    Point point4 = list[index];
                    flag2 = (num5 == point4.y % 2);
                }
                if (list2[num3] == Direction.U && flag2)
                {
                    Point point5 = list[index];
                    if (point5.y + 1 < height)
                    {
                        int[][] array2 = array;
                        Point point6 = list[index];
                        int[] obj = array2[point6.x];
                        Point point7 = list[index];
                        if (obj[point7.y + 1] == 0)
                        {
                            int[][] array3 = array;
                            Point point8 = list[index];
                            int[] obj2 = array3[point8.x];
                            Point point9 = list[index];
                            obj2[point9.y + 1] = 1;
                            List<Point> list3 = list;
                            Point point10 = list[index];
                            int x = point10.x;
                            Point point11 = list[index];
                            list3.Add(new Point(x, point11.y + 1));
                            flag = true;
                            goto IL_045d;
                        }
                    }
                }
                if (list2[num3] == Direction.D && !flag2)
                {
                    Point point12 = list[index];
                    if (point12.y - 1 >= 0)
                    {
                        int[][] array4 = array;
                        Point point13 = list[index];
                        int[] obj3 = array4[point13.x];
                        Point point14 = list[index];
                        if (obj3[point14.y - 1] == 0)
                        {
                            int[][] array5 = array;
                            Point point15 = list[index];
                            int[] obj4 = array5[point15.x];
                            Point point16 = list[index];
                            obj4[point16.y - 1] = 1;
                            List<Point> list4 = list;
                            Point point17 = list[index];
                            int x2 = point17.x;
                            Point point18 = list[index];
                            list4.Add(new Point(x2, point18.y - 1));
                            flag = true;
                            goto IL_045d;
                        }
                    }
                }
                if (list2[num3] == Direction.L)
                {
                    Point point19 = list[index];
                    if (point19.x - 1 >= 0)
                    {
                        int[][] array6 = array;
                        Point point20 = list[index];
                        int[] obj5 = array6[point20.x - 1];
                        Point point21 = list[index];
                        if (obj5[point21.y] == 0)
                        {
                            int[][] array7 = array;
                            Point point22 = list[index];
                            int[] obj6 = array7[point22.x - 1];
                            Point point23 = list[index];
                            obj6[point23.y] = 1;
                            List<Point> list5 = list;
                            Point point24 = list[index];
                            int x3 = point24.x - 1;
                            Point point25 = list[index];
                            list5.Add(new Point(x3, point25.y));
                            flag = true;
                            goto IL_045d;
                        }
                    }
                }
                if (list2[num3] == Direction.R)
                {
                    Point point26 = list[index];
                    if (point26.x + 1 < width)
                    {
                        int[][] array8 = array;
                        Point point27 = list[index];
                        int[] obj7 = array8[point27.x + 1];
                        Point point28 = list[index];
                        if (obj7[point28.y] == 0)
                        {
                            int[][] array9 = array;
                            Point point29 = list[index];
                            int[] obj8 = array9[point29.x + 1];
                            Point point30 = list[index];
                            obj8[point30.y] = 1;
                            List<Point> list6 = list;
                            Point point31 = list[index];
                            int x4 = point31.x + 1;
                            Point point32 = list[index];
                            list6.Add(new Point(x4, point32.y));
                            flag = true;
                        }
                    }
                }
                goto IL_045d;
                IL_045d:
                if (flag)
                {
                    num2++;
                    break;
                }
            }
            if (!flag)
            {
                list.RemoveAt(index);
            }
        }
        while (num2 != num);
        return array;
    }
}
